<?php

https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

1->介绍
   [SpringCloudAlibaba]是微服务领域又一'悍将', 和[Eureka, Spring]供应商, 并称SpringCloud微服务落地'三巨头'
   是什么:
   . 是阿里巴巴结合自身微服务实践, 开源的微服务全家桶
   . 在[SpringCloud]项目中孵化, 很可能成为[SpringCloud]第二代的标准实现
   . 业务流行广泛

   适用场景:
   . 大型复杂的系统, 例如大型电商系统
   . 高并发系统 (大型门户网站, 秒杀系统)
   . 需求不明确, 但变更较快的系统 (创业公司业务系统)

   优势:
   . 组件性能更强
   . 良好的可视化界面
   . 搭建简单, 上手快
   . 文档丰富, 而且还是中文


2->SpringCloud__Alibaba
   首先: [SpringCloudAlibaba]是基于[SpringCloud]的, [SpringCloud]是分布式系统的'工具集', 其自身又依赖[SpringBoot]
   -) 'SpringCloud版本命名'
      版本: 2.1.5.RELEASE
      . 2: 代表主版本, 第几代
      . 1: 次版本, 一些功能的增加, 但是架构没有发生变化
      . 5: 增量版本, bug修复
      . RELEASE: 里程碑 (SNAPSHOT => 开发版, M => 里程碑, RELEASE => 正式版)

      发布列车:
      Greewich SR1
      Greewich: release train (发布列车 -> 伦敦地铁站站名)
      Angel
      Brixton
      Camden
      Dalston
      Edgware
      Finchley
      Greenwich
      Hoxton

      SR: 表示该版本bug修复版
      RELEASE: 表示'正式版'
      发布: Greewich RELEASE ---> SR1 版本 ---> SR2 版本

   -) '版本兼容性'
      +==========================+==============================+==========================+
      |       Spring Cloud       |     Spring Cloud Alibaba     |        Spring Boot       |
      +==========================+==============================+==========================+
      |  Spring Cloud Greenwich  |        0.9.0.RELEASE         |       2.1.X.RELEASE      |
      +--------------------------+------------------------------+--------------------------+
      |  Spring Cloud Finchley   |        0.2.X.RELEASE         |       2.0.X.RELEASE      |
      +--------------------------+------------------------------+--------------------------+
      |  Spring Cloud Edgware    |        0.1.X.RELEASE         |       1.5.X.RELEASE      |
      +--------------------------+------------------------------+--------------------------+
      说明: 目前[SpringCloudAlibaba]还在'孵化阶段', 等孵化完成后, 只需关注SC和SB的版本就行.

   -) '版本选择'
      . 坚决不用非稳定版本[/end-of-life]版本
      . 尽量用最新一代
        - xxx.RELEASE 版本先缓一缓 (因为刚发布可能有些bug)
        - SR2 之后一般可以放心使用 (已经经过各大公司的锤炼了)

   -) '整合'
       说明: 因为[Spring-Cloud-Alibaba]需要依赖[Spring-Cloud], 所以要先整合Spring-Cloud
       详见: 附录/pom.xml
       - [Spring-Cloud]
       - [Spring-Cloud-Alibaba]
       <dependencyManagement>
          <dependencies>
            <!-- 整合spring cloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- 整合spring cloud alibaba -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>0.9.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
                </dependency>
           </dependencies>
       </dependencyManagement>


3->Nacos
   https://nacos.io/zh-cn/index.html
   服务提供者: 服务的被调用方 (即: 为其他微服务提供接口的微服务)
   服务消费者: 服务的调用方 (即: 调用其他微服务接口的微服务)

   -) '服务发现'
       简单理解:
       就是无论一个服务怎么变化, 另一个服务始终都能找到该服务提供的接口, 而找到并不是'凭空'找到的,
       而是通过一个'字典'获取到的, 这个字典一般叫做'注册中心', 这里以[MySql]作为注册中心来简单说明下:
       +-----------+                      +-----------+                      +-----------+
       |  Service1 |-------'insert'------>|   MySql   |<------'insert'------ |  Service2 |
       +-----+-----+                      +-----------+                      +-----+-----+
             |                                                                     |
             |                                                                     |
             +----------------------------- [相互调用] -----------------------------+

      [mysql.register]
      [id]    [service_name]       [ip]             [port]      [status]    [last_heartbeat]
       1       user-center         192.168.1.100     8080          UP          timestamp1
       2       content-center      192.168.1.200     8081          UP          timestamp2
       3       xxx-center          192.168.1.300     8082          DOWN        timestamp3

      说明:
      . 在每个微服务启动时, 都会向mysql注册中心插入一条自身信息, 用于注册自己
      . 其中注册信息维护了一个'存活状态', 用于'定期检测'该服务的状态'是否可用'
      . 各个服务之间调用时只需要查询mysql上的'存活状态', 获取各个微服务的信息, 用于自身接口调用
      . 服务下线时, 将自身信息从mysql删除

      弊端: 当mysql异常时, 整合服务调用全部不可用!
      解决: 各个微服务维护一份'本地缓存', 这样的话, 注册中心即使发生异常, 也不会影响各个服务之间的调用, 只不过是无法获取'最新服务'

   -) 'Nacos'
       上面我们已经引入了'服务发现-注册中心'的概念, 而且使用[mysql]做了一版, 那么[Nacos]也是'服务发现'组件,
       充当[注册中心 + 配置中心]的角色, 而且功能还远不止于此...
       +--------------+                      +-----------+                      +--------------+
       |   Service1   |-------'insert'------>|   Nacos   |<------'insert'------ |   Service2   |
       | nacos client |                      |  Server   |                      | nacos client |
       +------+-------+                      +-----------+                      +------+-------+
              |                                                                        |
              |                                                                        |
              +------------------------------- [相互调用] ------------------------------+

       说明: 各个微服务集成'nacos-client', 然后向注册中心'nacos-server'注册自身服务, 剩下的交由Nacos来处理就OK了...


4->Nacos_Serer
   1). [下载]
       - 从pom点进去[alibaba], 查看对应的[client]是哪个版本, 然后就下载对应的[server]版本
       - https://github.com/alibaba/nacos/releases

   2). [启动]
       - [bin]目录
       . [win]: startup.cmd -m standalone
       . [Linux/Unix/Mac]: sh startup.sh -m standalone

   3). [访问]
       ip:8848/nacos/index.html
       - 8848: 珠穆朗玛峰高度
       - nacos/nacos


5->Nacos_Client
   注册中心已经准备完毕, 那么接下来就把服务注册上去
   -) '整合'
       1. [pom]
          <!-- pring-cloud-starter-{spring cloud子项目的名称}-[{模块名称}] -->
          <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
          </dependency>

       2. [注解]
          @EnableDiscoveryClient (早先的需要, 现在不需要也可以)

       3. [配置文件]
          spring.application.name=user-center         // 这里的名称尽量使用[-], 不要使用[_], 更不要使用[特殊字符]
          spring.cloud.nacos.discovery.server-addr=localhost:8848
       注意: 如果存在'Eureka'的依赖的话, 会报'2个注册中心异常', 解决方案: A: 去掉Eureka依赖; B: 配置文件移除Eureka的服务发现
       spring.autoconfigure.exclude: org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration

   -) '测试'
       // consul / eureka / zookeeper...
       private DiscoveryClient discovery;    // Spring-Cloud提供服务发现
       @GetMapper("instances")
       public List<ServiceInstance> getInstances() {
          return discovery.getInstances("user-center");
       }
       说明:
       . '动态感知'并返回该服务名下的'所有实例集合'
       . 但是请求时比较麻烦, 需要根据返回的'实例'进行拼接, 然后借助'restTemplate'进行请求


6->服务发现的领域模型
   -) '模型'
       +=============================================================+
       |                        ['Namespace']                        |
       |    +---------------------------------------------------+    |
       |    |                     ['Group']                     |    |
       |    |    +-----------------------------------------+    |    |
       |    |    |               ['Service']               |    |    |
       |    |    |  +---------------+   +---------------+  |    |    |
       |    |    |  | ['Cluster1']  |   | ['Cluster2']  |  |    |    |
       |    |    |  | +-----------+ |   | +-----------+ |  |    |    |
       |    |    |  | | Instance1 | |   | | Instance3 | |  |    |    |
       |    |    |  | | Instance2 | |   | | Instance4 | |  |    |    |
       |    |    |  | +-----------+ |   | +-----------+ |  |    |    |
       |    |    |  +---------------+   +---------------+  |    |    |
       |    |    |                                         |    |    |
       |    |    +-----------------------------------------+    |    |
       |    |                                                   |    |
       |    +---------------------------------------------------+    |
       |                                                             |
       +=============================================================+

       说明:
       Namespace: 命名空间 (不同的环境使用不同的命名空间'实现隔离', 彼此之间互不干扰, 默认'public')
       // Group:     不同服务可以划分到一个组, 默认[DEFAULT_GROUP] (暂时不用)
       Service:   服务名称 (用户微服务, 角色微服务...)
       Cluster:   集群名称 (对指定微服务的一个'虚拟划分', 也可以做'CND'就近访问, 这样在'容灾+性能'都有顾及到, 默认[DEFAULT] 各个微服务下的'集群', 比如: BJ(北京), SH(上海))
       Instance:  实例名称 (各个微服务的'实例')

       配置:
       spring.cloud.nacos.discovery.namespace=672737167-d826-4das-8632-ajk67ahgyajs     // 使用[UUID]
       spring.cloud.nacos.discovery.cluster-name=SH                             // 部署在[上海机房]
       注意:
       1. [namespace]的配置前提, 是已经在'Nacos-Server'上面已经创建好了, 然后使用生成的[UUID], 作为'配置文件'的值
       2. 不同的命名空间对应不同的服务, 可以理解为: 服务只能找到'相同命名空间'内的服务!
          如果两个服务指定了命名空间, 并且服务之间有调用关系, 那么就'一定要在同一命名空间!'

   -) '元数据'
       描述:
       Nacos数据（如配置和服务）描述信息，如服务版本、权重、容灾策略、负载均衡策略、鉴权配置、各种自定义标签 (label)，
       从作用范围来看，分为服务级别的元信息、集群的元信息及实例的元信息。

       级别: 实例级别 (暂时没有: 服务级别, 集群级别...)

       作用:
       . 提供描述信息
       . 让微服务调用更加灵活
         - 例如: 微服务版本控制 (这个一般在C端场景比较多! 用户不升级版本, 那么接口在功能上就要兼容!)
           [内容中心V1] ------> [用户中心V1]
           [内容中心V2] ------> [用户中心V2]

       设置元数据:
       . 通过控制台设置
       . 配置文件设置
         spring.cloud.nacos.discovery.metadate.instance=c
         spring.cloud.nacos.discovery.metadate.name=xiaomu
         spring.cloud.nacos.discovery.metadate.version=v1
